(function() {
    var _requestIndex = 1;
    var _requestQueue = {}; // 等待响应的请求队列

    var _requestBuffer = []; // 缓冲连接未就绪时的请求

    var _requestSerialization; // 这里始终用最后一个请求的，不支持不同请求的序列化方式不同

    var _websocket;

    var _queuePut = function(_requestId, _request) {
        console.log('_queuePut', _requestId);

        _requestQueue["request-" + _requestId] = _request; // 加入队列等待回调
    };

    var _queueGet = function(_requestId) {
        return _requestQueue["request-" + _requestId]; // 从队列中取出请求
    };

    var _queueDelete = function(_requestId) {
        console.log('_queueDelete', _requestId);

        delete _requestQueue["request-" + _requestId]; // 从队列中移除
    };

    // 收消息回调
    var _onMessage = function(_messageEvent) {
        var _responseEntity = _requestSerialization.deserialize(_messageEvent.data); // 反序列化

        var _requestId = _responseEntity.requestId;
        var _request = _queueGet(_requestId); // 从队列中取出请求

        if (!!!_request) {
            console.error(19, 'req not found', _requestId, _requestQueue);
        }

        var _responseBody = _responseEntity.result;
        _request.responseBody = _responseBody;

        _request.responseHandler(_request); // 执行回调

        _queueDelete(_requestId); // 从队列中移除
    };

    // 封装发消息，如果未就绪，就加入缓冲
    var _sendMessage = function(_requestMessage) {
        var _ws = _getWebsocket();
        if (!!_ws && 1 == _ws.readyState) {
            _ws.send(_requestMessage); // 发请求消息
        }

        _requestBuffer.push(_requestMessage);
    };

    var _onError = function(a) {
        console.log('_onError', a);
    };

    // 连接就绪后，发送缓冲区的请求
    var _onOpen = function(a) {
        _requestBuffer.forEach(function(_req) {
            console.log(48, 'forEach _send _onOpen', _req);
            _sendMessage(_req);
        });
        _requestBuffer = [];
    };

    // CONNECTING：值为0，表示正在连接。
    // OPEN：值为1，表示连接成功，可以通信了。
    // CLOSING：值为2，表示连接正在关闭。
    // CLOSED：值为3，表示连接已经关闭，或者打开连接失败。
    var _getWebsocket = function() {
        if (!!_websocket && (0 == _websocket.readyState || 1 == _websocket.readyState)) {
            return _websocket;
        }

        var _url = "ws://" + location.host + "/ws"; // 完整路径
        _websocket = new WebSocket(_url);
        _websocket.onopen = _onOpen;
        _websocket.onerror = _onError;
        _websocket.onmessage = _onMessage;
        return _websocket;
    };

    // 发消息
    var WebSocketTransporter = function(_request) {
        var _requestId = _requestIndex++;
        _queuePut(_requestId, _request);

        var _requestEntity = {
            "requestId" : _requestId,
            "interfaceName" : _request.interfaceName,
            "methodName" : _request.methodName,
            "args" : _request.args
        };

        _requestSerialization = _request.serialization; // 保存，返回时会使用
        var _requestMessage = _requestSerialization.serialize(_requestEntity);
        _sendMessage(_requestMessage);
    };

    // 挂载根对象
    var _root = null;

    if (!!window) {
        _root = window; // 浏览器环境, 挂载到window
    } else if (!!wx) {
        _root = wx; // 微信小程序, 挂载到wx
    } else {
        throw "window or wx not found, contact the developer now";
    }

    _root.WebSocketTransporter = WebSocketTransporter;
})();